/**
 * @constructor
 * @param {number} x
 * @param {number} y
 * @param {number} g
 * @param {number} h
 * @returns {Node}
 */
function Node(x, y, g, h) {
	
	/**
	 * @public  
	 */
	this.x = x;
	
	/**
	 * @public  
	 */
	this.y = y;
	
	/**
	 * @public  
	 */
	this.g = g;
	
	/**
	 * @public  
	 */
	this.h = h;
	
	/**
	 * @private
	 */
	this.hash = 7;
	this.hash = 71 * this.hash + x;
	this.hash = 71 * this.hash + y;
	
	/**
	 * @private
	 */
	this.hCode = this.hash;
	
	/**
	 * @private
	 */
	this.parent = null;
	
	/**
	 * @private
	 */
	this.parentsCount = 0;
	
};

Node.prototype = {
		
		/**
		 * @public 
		 * @memberOf Node.prototype
		 * @returns{Node} parent node
		 */
		getParent: function() {
			return this.parent;
		},
		
		
		/**
		 * @public 
		 * @memberOf Node.prototype
		 * @param{Node} node Parent
		 */
		setParent: function(node) {
			this.parentsCount = node.getParentsCount() + 1;
			this.parent = node;
		},
		
		/**
		 * @public 
		 * @memberOf Node.prototype
		 * @returns {Number} this Node's parents count
		 */
		getParentsCount: function() {
			return this.parentsCount;
		},
		
		/**
		 * @public 
		 * @memberOf Node.prototype
		 * @returns {Number} the sum of {@link Node#g} + {@link Node#h}
		 */
		getF: function() {
			return this.g + this.h;
		},
		
		
		/**
		 * @public 
		 * @memberOf Node.prototype
		 * @returns {Number}
		 */
		hashCode: function() {
			return this.hCode;
		},
		
		/**
		 * @public 
		 * @memberOf Node.prototype
		 * @param {Node} node Other node
		 * @returns {Boolean}
		 */
		equals: function(node) {
			return this.hashCode() == node.hashCode();
		},
		
		/**
		 * @public 
		 * @memberOf Node.prototype
		 * @returns {string}
		 */
		toString: function() {
			return "["+this.x+":"+this.y+" "+this.getF().toFixed(2)+"]";
		},
		
		/**
		 * @public 
		 * @memberOf Node.prototype
		 * @returns {string}
		 */
		toDetailedString: function() {
			return "["+this.x+":"+this.y+" "+this.g.toFixed(2)+" + "+this.h.toFixed(2) + " = " + this.getF().toFixed(2);
		}
};